import { history, Effect, Reducer } from 'umi';
import { message } from 'antd';
import { getPageSize } from '@/utils/pdfUtils';
import { serverBmp } from '@/utils/utils';

import {
  queryUnitById,
  queryMajorListByUid,
  queryBlueprintById,
  queryBlueprintListByMid,
  addBlueprint,
  uploadPdf,
  queryBlueprintHistoryListByBid,
  createIssue,
  queryIssue,
  queryBlueprintIssue,
  getBase64String,
  invocations,
} from '../service';

import { BlueprintItem, MajorListItem, UnitListItem, BlueprintListItem } from '../data.d';

// const CompareResult = require('./compareResult.json');

const transMark = (page: number, sourceData: [], { width = 0, height = 0 }) => {
  return sourceData.map((mark: any) => {
    const x = mark[0];
    const y = mark[1];
    const w = mark[2];
    const h = mark[3];
    return {
      page,
      type: 'rect',
      data: {
        x: x * width,
        y: y * height,
        width: w * width,
        height: h * height,
      },
    };
  });
};

export interface ConnectState {
  project: StateType;
}

export interface StateType {
  pdfLoading: boolean;
  mPdfLoading: boolean;
  oPdfLoading: boolean;
  unitProject?: UnitListItem;
  blueprintList: BlueprintItem[];
  drawingUrl: string;
  drawingMarks: any[];
  bpHistory: any[];
  issueList: any[];
  pdfMarkable: boolean;
  // 意见菜单状态
  issueListState: {
    expandedKeys: string[];
    checkedKeys: string[];
    selectedKeys: string[];
    autoExpandParent: boolean;
    selectedBph: any[];
  };
  // 比对列表
  compareList: any[];
  compareMarks: [any[], any[]];
  collapsed: boolean; // 审查意见折叠框
  editIssueCollapsed: boolean; // 修改和查看审查意见折叠框
  editIssueReadonly: boolean;
  editIssueFormValues: {
    bhid: string;
    opinion?: string;
  };
  // 专业菜单状态
  majorMenuState: {
    openKeys: string[];
    selectedKey: string;
    // 当前选中的图纸记录
    selectedBp: any;
  };
  activeTabKey: string;
}

export interface ModelType {
  namespace: string;
  state: StateType;
  effects: {
    fetch: Effect;
    fetchBlueprint: Effect;
    fetchBlueprintById: Effect;
    addBlueprint: Effect;
    fetchBlueprintHistoryListByBid: Effect;
    fetchBlueprintIssue: Effect;
    addIssue: Effect;
    queryIssue: Effect;
    uploadPdf: Effect;
    pdfCompare: Effect;
    changeState: Effect;
  };
  reducers: {
    save: Reducer<StateType>;
    clear: Reducer<StateType>;
  };
}

const Model: ModelType = {
  namespace: 'project',

  state: {
    pdfLoading: false,
    mPdfLoading: false,
    oPdfLoading: false,
    unitProject: undefined,
    blueprintList: [],
    drawingUrl: '',
    drawingMarks: [],
    issueList: [],
    pdfMarkable: false,
    bpHistory: [],
    compareList: [],
    compareMarks: [[], []],
    issueListState: {
      expandedKeys: [],
      checkedKeys: [],
      selectedKeys: [],
      autoExpandParent: false,
      selectedBph: [],
    },
    collapsed: true,
    editIssueCollapsed: true,
    editIssueReadonly: true,
    editIssueFormValues: {
      bhid: '',
    },
    // 专业菜单状态
    majorMenuState: {
      openKeys: [],
      selectedKey: '',
      // 当前选中的图纸记录
      selectedBp: {},
    },
    activeTabKey: '1',
  },

  effects: {
    *fetch({ payload }, { call, put }) {
      const unit = yield call(queryUnitById, payload);
      if (unit && unit.code === 0) {
        const major = yield call(queryMajorListByUid, payload);
        if (major && major.code === 0) {
          const { majorList } = major;
          const blueprintList = majorList.map((m: MajorListItem) => ({
            id: m.id,
            title: m.name,
            subItem: [],
            pid: m.pid,
            uid: m.uid,
          }));
          yield put({
            type: 'save',
            payload: {
              unitProject: unit.unit,
              blueprintList,
            },
          });
        } else {
          history.replace('/exception/404');
        }
      } else {
        history.replace('/exception/404');
      }
    },
    *fetchBlueprint({ payload }, { select, call, put }) {
      const response = yield call(queryBlueprintListByMid, payload);
      if (response) {
        const mid = payload;
        const blueprintList = yield select((state: ConnectState) => state.project.blueprintList);
        const bpList = response.list;
        const selectedBp =
          bpList.length > 0
            ? {
                ...bpList[0],
                title: bpList[0].name,
                url: `${serverBmp}${bpList[0].url}`,
              }
            : {};
        const majorMenuState = yield select((state: ConnectState) => state.project.majorMenuState);
        yield put({
          type: 'save',
          payload: {
            drawingUrl: selectedBp.url,
            drawingMarks: [],
            pdfMarkable: true,
            majorMenuState: {
              ...majorMenuState,
              selectedKey: selectedBp.id,
              selectedBp,
            },
            blueprintList: blueprintList.map((m: BlueprintItem) => {
              if (m.id === mid) {
                return {
                  ...m,
                  subItem: bpList.map((item: BlueprintListItem) => ({
                    ...item,
                    title: item.name,
                    url: `${serverBmp}${item.url}`,
                    version: item.version,
                  })),
                };
              }
              return m;
            }),
          },
        });
      }
    },
    *fetchBlueprintById({ payload, callback }, { call }) {
      const response = yield call(queryBlueprintById, payload);
      if (response && response.code === 0) {
        if (callback) callback(response.blueprint);
      }
    },
    *fetchBlueprintHistoryListByBid({ payload, callback }, { call }) {
      const response = yield call(queryBlueprintHistoryListByBid, payload);
      if (response && response.code === 0) {
        const list = response.list.map((l: any) => ({
          ...l,
          url: `${serverBmp}${l.url}`,
        }));
        if (callback) callback(true, list);
      }
      if (callback) callback(false);
    },
    *addBlueprint({ payload, callback }, { select, call, put }) {
      const {
        formValues: { id, file, title },
        mid,
      } = payload;
      const upload = yield call(uploadPdf, file);
      if (upload && upload.code === 0) {
        const response = yield call(addBlueprint, { mid, name: title, url: upload.url, id });
        if (response && response.code === 0) {
          message.success('添加成功');
          const { data = [] } = response;
          let newBp: any = null;
          if (data.length > 0) {
            newBp = {
              ...data[0],
              title: data[0].name,
              url: `${serverBmp}${data[0].url}`,
            };
          }
          const blueprintList = yield select((state: ConnectState) => state.project.blueprintList);
          const majorMenuState = yield select(
            (state: ConnectState) => state.project.majorMenuState,
          );
          yield put({
            type: 'save',
            payload: {
              majorMenuState: {
                ...majorMenuState,
                selectedKey: newBp && newBp.id,
                // 当前选中的图纸记录
                selectedBp: newBp,
              },
              pdfMarkable: true,
              drawingUrl: newBp && newBp.url,
              drawingMarks: [],
              blueprintList: blueprintList.map((m: BlueprintItem) => {
                if (m.id === mid) {
                  return {
                    ...m,
                    subItem: data.map((item: BlueprintListItem) => ({
                      ...item,
                      title: item.name,
                      url: `${serverBmp}${item.url}`,
                      version: item.version,
                    })),
                  };
                }
                return m;
              }),
            },
          });
          if (callback) {
            callback(true, newBp);
          }
        } else {
          message.success('添加失败');
          if (callback) {
            callback(false);
          }
        }
      } else {
        message.error(`上传图片失败，${upload.msg}`);
      }
    },
    *uploadPdf({ payload, callback }, { call }) {
      const response = yield call(uploadPdf, payload);
      if (callback) callback(response);
    },
    *addIssue({ payload, callback }, { call, put }) {
      const response = yield call(createIssue, payload);
      if (response && response.code === 0) {
        yield put({
          type: 'save',
          payload: {
            drawingMarks: [],
            pdfMarkable: false,
            collapsed: true,
            activeTabKey: '2',
          },
        });
        yield put({
          type: 'fetchBlueprintIssue',
          payload: {
            bid: response.issue.bid,
          },
          callback: (success: boolean, issueList: any[]) => {
            if (callback) callback(success, issueList);
          },
        });
      }
    },
    *queryIssue({ payload, callback }, { call, put }) {
      const response = yield call(queryIssue, payload);
      if (response && response.code === 0) {
        yield put({
          type: 'save',
          payload: {
            issueList: response.list,
          },
        });
        if (callback) callback(true, response.list);
      }
      if (callback) callback(false);
    },
    *fetchBlueprintIssue({ payload, callback }, { call, put }) {
      const response = yield call(queryBlueprintIssue, payload);
      if (response && response.code === 0) {
        const list = response.list.map((l: any) => ({
          ...l,
          url: `${serverBmp}${l.url}`,
        }));
        const issueListState: {
          expandedKeys: string[];
          checkedKeys: string[];
          selectedKeys: string[];
          autoExpandParent: boolean;
          selectedBph: any;
        } = {
          expandedKeys: [],
          checkedKeys: [],
          selectedKeys: [],
          autoExpandParent: false,
          selectedBph: {},
        };
        if (list.length > 0) {
          issueListState.checkedKeys = [list[0].id];
          issueListState.expandedKeys = [list[0].id];
          issueListState.autoExpandParent = false;
          [issueListState.selectedBph] = list;
        }
        yield put({
          type: 'save',
          payload: {
            issueListState,
            bpHistory: list,
          },
        });
        if (callback) callback(true, response.list);
      }
      if (callback) callback(false);
    },
    *pdfCompare(_, { select, call, put }) {
      const compareList = yield select((state: ConnectState) => state.project.compareList);
      if (compareList && Array.isArray(compareList) && compareList.length === 2) {
        const base64Files = yield call(getBase64String, {
          mUrl: compareList[0].url,
          oUrl: compareList[1].url,
        });
        if (base64Files && base64Files.code === 0) {
          const { m, o } = base64Files;
          const response = yield call(invocations, { m, o });
          if (response) {
            const {
              // information,
              page_bbox: pageBbox,
            } = response[0];
            // const { miss, increas } = information;
            const compareMarks = yield select((state: ConnectState) => state.project.compareMarks);
            for (let i = 0; i < pageBbox.length; i += 1) {
              const { relation, m_bbox: mBbox, o_bbox: oBbox } = pageBbox[i];
              const mPage: number = relation[0];
              const mSize = yield getPageSize({ url: compareList[0].url, page: mPage + 1 });
              compareMarks[0] = compareMarks[0].concat(
                transMark(mPage + 1, mBbox, { width: mSize.width, height: mSize.height }),
              );
              const oPage: number = relation[1];
              const oSize = yield getPageSize({ url: compareList[1].url, page: oPage + 1 });
              compareMarks[1] = compareMarks[1].concat(
                transMark(oPage + 1, oBbox, { width: oSize.width, height: oSize.height }),
              );
            }
            yield put({
              type: 'save',
              payload: {
                compareMarks,
              },
            });
          }
        }
      }
    },
    *changeState({ payload, callback }, { put }) {
      yield put({
        type: 'save',
        payload,
      });
      if (callback) {
        callback();
      }
    },
  },

  reducers: {
    save(state, { payload }) {
      return {
        ...state,
        ...payload,
      };
    },
    clear() {
      return {
        pdfLoading: false,
        mPdfLoading: false,
        oPdfLoading: false,
        unitProject: undefined,
        blueprintList: [],
        drawingUrl: '',
        drawingMarks: [],
        issueList: [],
        pdfMarkable: false,
        bpHistory: [],
        compareList: [],
        compareMarks: [[], []],
        issueListState: {
          expandedKeys: [],
          checkedKeys: [],
          selectedKeys: [],
          autoExpandParent: false,
          selectedBph: [],
        },
        collapsed: true,
        editIssueCollapsed: true,
        editIssueReadonly: true,
        editIssueFormValues: {
          bhid: '',
        },
        // 专业菜单状态
        majorMenuState: {
          openKeys: [],
          selectedKey: '',
          // 当前选中的图纸记录
          selectedBp: {},
        },
        activeTabKey: '1',
      };
    },
  },
};

export default Model;
